/* eslint-disable no-prototype-builtins */

/** 将数组中为空的值去掉
 * @param {Array} actual
 * @returns {Array}
 */
export function clearBlank(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i] && actual[i] !== '') {
      newArray.push(actual[i])
    }
  }
  return newArray
}

/** 将字符串数组转成整形数组
 * @param {Array} arySource 数组中每个元素都是字符串
 * @returns {Array} 将字符串转成整型
 */
export function transAryStr2Int(arySource) {
  for (let i = 0; i < arySource.length; i++) {
    arySource[i] = Number(arySource[i])
  }
  return arySource
}

/** 判断是否是一个数组 */
export const isArray = function (arr) {
  return Object.prototype.toString.call(arr) === '[object Array]'
}

/** 判断是否是空数组 */
export const isBlankAry = function (arr) {
  if (!arr) return true
  return JSON.stringify(arr) === '[]'
}

/** 数组去重 1，适合数组成员是字符串、数字型
 * @param {Array} arr
 * @returns {Array}
 */
export function unique(arr) {
  if (arr instanceof Array) {
    // Set数据结构，它类似于数组，其成员的值都是唯一的
    // 利用Array.from将Set结构转换成数组
    return Array.from(new Set(arr))
  } else return arr
}

/** 数组去重 2，适合数组成员是对象 */
export function uniqueObjAry(ary) {
  const aryReturn = {}
  return ary.filter((item) => {
    if (!aryReturn[item]) {
      aryReturn[item] = true
      return true
    }
  })
}

/** 数组去重 3，适合数组成员是对象，根据成员对象的某个属性判断 */
export function uniqueObjAryProp(ary, propName) {
  const aryReturn = {}
  return ary.reduce(function (preValue, item) {
    // 上一次调用回调返回的值，或者是提供的初始值
    // console.log(preValue, '--')
    // 下一个要遍历的数组成员
    // console.log(item, '++')
    // 下面这句话是首先是判断当前数组成员的key是否存在于 aryReturn 中，
    // 如果已经存在，将这个 aryReturn 中的 key 设置为空，并且值设置为true，再将当前数组成员添加到返回值中
    // 如果不存在，aryReturn 中的 key 为当前数组成员的 key，并且值设置为true，再将当前数组成员添加到返回值中
    aryReturn[item[propName]] ? '' : (aryReturn[item[propName]] = true && preValue.push(item))
    return preValue
  }, [])
}

/** 数组去重 3，适合数组成员是字符串、数字型 */
export function unique4Object2(arr) {
  var aryReturn = []
  arr.forEach((ele) => {
    if (aryReturn.indexOf(ele) === -1) {
      aryReturn.push(ele)
    }
  })
  return aryReturn
}

/** 判断两个数组是否相等 */
export const arrayEqual = function (arr1, arr2) {
  if (arr1 === arr2) return true
  if (arr1.length !== arr2.length) return false
  for (let i = 0; i < arr1.length; ++i) {
    if (arr1[i] !== arr2[i]) return false
  }
  return true
}

/** 将json对象转成数组
 * @param {Object} json
 * @returns {Array}
 */
export function json2Array(json) {
  if (!json) return ''
  return clearBlank(
    Object.keys(json).map((key) => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    })
  ).join('&')
}

/** 将 objcet 对象转成数组
 * @param {Object} objcet
 * @returns {Array}
 */
export function obj2Array(obj) {
  // obj 为 undefined 时， 也会得到与 null 相同的结果
  // 虽然 null 和 undefined 不一样，因此只需写一种即可
  // if (typeof (obj) === 'undefined' || !obj) return null
  if (!obj) return null
  if (typeof obj !== 'object') return null
  const tmp = []
  for (var key in obj) {
    tmp.push(key)
  }
  return tmp
}

/** 判断数组中是否有某个值
 * @param {Array} arr 要验证的数组
 * @param {Object} obj 某个值
 * @returns {Boolean} 是否包含某个值
 */
export function IsAryContainVal(ary, obj) {
  for (let i = 0; i < ary.length; i++) {
    if (ary[i] === obj) {
      return true
    }
  }
  return false
}

/** 删除数组中某个指定值的元素
 * @param {Array} arr 要删除元素的数组
 * @param {Object} obj 某个指定值的元素
 * @returns {Array} 删除操作后的新数组
 */
export function AryRemoveVal(ary, obj) {
  if (!isArray(ary)) {
    return ary
  }
  return ary.filter(function (item) {
    return item != obj
  })
}

/**
 * @description 将数组转成树形数据，要求原数组带id和idParent属性
 * @param {Array} aryData 平板数据
 * @param {Number} idRoot rootId
 * @returns {Array} 带children的树形数据
 */
export function AryToTree(aryData, idRoot) {
  // 对源数据深度克隆
  const cloneData = JSON.parse(JSON.stringify(aryData))
  /**
   * filter的用法
   * var ages = [32, 33, 16, 40]
   * function checkAdult(age) {
   *   return age >= 18
   * }
   * console.log(ages.filter(checkAdult))
   */
  let aryRoot = aryData.filter((item) => {
    return item.id === idRoot
  })

  const aryReturn = cloneData.filter((father) => {
    // 返回每一项的子级数组
    const aryBranch = cloneData.filter((child) => {
      return father.id === child.idParent
    })
    // 给父级添加一个children属性，并赋值
    father.children = aryBranch.length > 0 ? aryBranch : []
    // 返回第一层
    return father.idParent === idRoot
  })
  if (aryRoot.length > 0) {
    aryRoot[0].children = aryReturn
  } else {
    aryRoot = aryReturn
  }
  return aryRoot
}

/** 数组排序 */
// 快排 [left] + min + [right]
export function quickArr(arr) {
  if (arr.length <= 1) {
    return arr
  }
  var left = []
  var right = []
  var pIndex = Math.floor(arr.length / 2)
  var p = arr.splice(pIndex, 1)[0]
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] <= p) {
      left.push(arr[i])
    } else {
      right.push(arr[i])
    }
  }
  // 递归
  return quickArr(left).concat([p], quickArr(right))
}

/** 冒泡排序 1 */
export function sortBubble1(arr) {
  var len = arr.length
  for (var i = 0; i < len - 1; i++) {
    for (var j = i + 1; j < len; j++) {
      if (arr[i] > arr[j]) {
        var temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
      }
    }
  }
  return arr
}

/** 冒泡排序 2 */
export function sortBubble2(arr) {
  var len = arr.length
  for (var i = 0; i < len - 1; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        var temp = arr[j]
        arr[j] = arr[j + 1]
        arr[j + 1] = temp
      }
    }
  }
  return arr
}

/** 深克隆（深克隆不考虑函数） */
export function deepClone(obj, res) {
  const result = res || {}
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      if (typeof obj[prop] === 'object' && obj[prop] !== null) {
        // 引用值(obj/array)且不为null
        if (Object.prototype.toString.call(obj[prop]) === '[object Object]') {
          // 对象
          result[prop] = {}
        } else {
          // 数组
          result[prop] = []
        }
        deepClone(obj[prop], result[prop])
      } else {
        // 原始值或func
        result[prop] = obj[prop]
      }
    }
  }
  return result
}

/** 深浅克隆是针对引用值 */
export function deepClone1(target) {
  if (typeof target !== 'object') {
    return target
  }
  var result
  if (Object.prototype.toString.call(target) === '[object Array]') {
    // 数组
    result = []
  } else {
    // 对象
    result = {}
  }
  for (var prop in target) {
    if (target.hasOwnProperty(prop)) {
      result[prop] = deepClone(target[prop])
    }
  }
  return result
}

/** 为树形数据所有父节点添加 disabled 属性
 * @param {Array} treeData: 树形数据
 */
export function addKey(treeData) {
  return treeData.map((item) => ({
    ...item,
    disabled: item.children?.length > 0 ? true : false,
    children: item.children ? addKey(item.children) : [],
  }))
}
